package cn.tuling.example;

/**
 * 例子：用命令模式实现客户去餐馆吃早餐
 * <p>
 * 客户去餐馆可选择的早餐有肠粉、河粉和馄饨等，客户可向服务员选择以上早餐中的若干种，服务员将客户的请求交给相关的厨师去做。
 * 这里的点早餐相当于“命令”，服务员相当于“调用者”，厨师相当于“接收者”，所以用命令模式实现比较合适。
 */
public class CommandTest {
    public static void main(String[] args) {
        // 一个厨师
        BreakfastChef chef = new ConcreteChef();


        // 一个服务员
        Waiter waiter = new Waiter();

        // N个命令
        waiter.setChangFen(new ChangFenCommand(chef));
        waiter.setHuntun(new HunTunCommand(chef));
        waiter.setHefen(new HeFenCommand(chef));

        waiter.chooseChangfen();
        waiter.chooseHeFen();
        waiter.chooseHunTun();
    }
}

// 厨师：接收者
interface BreakfastChef {
    void cookingChangFen();

    void cookingHunTun();

    void cookingHeFen();
}

class ConcreteChef implements BreakfastChef {

    @Override
    public void cookingChangFen() {
        System.out.println("完成肠粉。");
    }

    @Override
    public void cookingHunTun() {
        System.out.println("完成馄饨。");
    }

    @Override
    public void cookingHeFen() {
        System.out.println("完成河粉。");
    }
}

// 命令： 点早餐
interface BreakFastCommand {
    void cooking();
}

class ChangFenCommand implements BreakFastCommand {
    private BreakfastChef chef;

    public ChangFenCommand(BreakfastChef chef) {
        this.chef = chef;
    }

    @Override
    public void cooking() {
        chef.cookingChangFen();
    }
}

class HunTunCommand implements BreakFastCommand {
    private BreakfastChef chef;

    public HunTunCommand(BreakfastChef chef) {
        this.chef = chef;
    }

    @Override
    public void cooking() {
        chef.cookingHunTun();
    }
}

class HeFenCommand implements BreakFastCommand {
    private BreakfastChef chef;

    public HeFenCommand(BreakfastChef chef) {
        this.chef = chef;
    }

    @Override
    public void cooking() {
        chef.cookingHeFen();
    }
}

// 调用者：服务员
class Waiter {
    private BreakFastCommand changfen, huntun, hefen;

    public void setChangFen(BreakFastCommand command) {
        this.changfen = command;
    }

    public void setHuntun(BreakFastCommand huntun) {
        this.huntun = huntun;
    }

    public void setHefen(BreakFastCommand hefen) {
        this.hefen = hefen;
    }

    public void chooseChangfen() {
        changfen.cooking();
    }

    public void chooseHunTun() {
        huntun.cooking();
    }

    public void chooseHeFen() {
        hefen.cooking();
    }
}